/**
 * @description jx时间处理类
 * @author xiaodong.zhang
 * @example
 * import data from './Date'
 * this.$jxUtils.date.getTimeStamp(2021-09-10 23:00:20) // 转换时间戳
 * this.$jxUtils.date.dateFmt('yyyy-MM-dd hh:mm:ss','1631286020000') //2021-09-10 23:00:20
 * this.$jxUtils.date.dateAdd("h", 1) // 返回一小时后时间戳
 * this.$jxUtils.date.latelyDate(7) // 最近7天时间段 [2021-08-10,2021-08-17]
 * this.$jxUtils.date.transLocalTimeBjTime('2015-05-09 11:29:23') // 返回转换后的北京时间
 * this.$jxUtils.date.transBjTimeLocalTime('2015-05-09 11:29:23') // 把北京时间转换为当地时间
 * ...
 *
 */
class JxDateClass {
  constructor() {}
  /**
   * @param {string} dataStr  字符串格式为 2017-02-10 18:20:30
   * @description 注意：此处月、日、时分秒、必须为2位数字，否则报错
   * @returns {number} 时间戳
   * @author xiaodong.zhang
   * @example
   * this.$jxUtils.date.getTimeStamp('2021-09-10 23:00:20') //1631286020000
   */
  getTimeStamp(dataStr = this.dateFmt('yyyy-MM-dd hh:mm:ss')) {
    return Date.parse(new Date(dataStr))
  }

  /**
   * @param {string} fmt
   * @param {date} date Date()
   * @returns {string}  时间字符串  如yyyy-MM-dd 2021-09-01 、 yyyy-MM-dd hh:mm:ss2014-01-01 01:20:20
   * @author xiaodong.zhang
   * @example
   * this.$jxUtils.date.dateFmt() //2021-09-07
   * this.$jxUtils.date.dateFmt('yyyy-MM-dd hh:mm:ss','1631286020000') //2021-09-10 23:00:20
   */
  dateFmt(fmt = 'yyyy-MM-dd', date = new Date()) {
    if (date instanceof Date) {
      date = date
    } else {
      date = new Date(date)
    }

    let dateType = {
      'M+': date.getMonth() + 1, //月份
      'd+': date.getDate(), //日
      'h+': date.getHours(), //小时
      'm+': date.getMinutes(), //分
      's+': date.getSeconds(), //秒
      'q+': Math.floor((date.getMonth() + 3) / 3), //季度
      S: date.getMilliseconds() //毫秒
    }
    if (/(y+)/.test(fmt)) {
      fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length))
    }
    for (let k in dateType)
      if (new RegExp('(' + k + ')').test(fmt))
        fmt = fmt.replace(
          RegExp.$1,
          1 === RegExp.$1.length ? dateType[k] : ('00' + dateType[k]).substr(('' + dateType[k]).length)
        )
    return fmt
  }

  /**
   *
   * @param {string} part 计算的日期节点  y年、M月、d日、h时、m分 、s秒
   * @param {number} value 正整数 负整数 如 -1 、2
   * @param { * } date 可选 传递日期字符串、时间戳、日期对象， 如果有用此时间作为计算目标，如果没有取当前时间
   * @author xiaodong.zhang
   * @returns {string} 返回计算后的时间戳
   * @example
   * this.$jxUtils.date.dateAdd("y", -1) // 返回去年日期时间戳
   * this.$jxUtils.date.dateAdd("y", -1) // 返回明年日期时间戳
   * this.$jxUtils.date.dateAdd("M", 3) // 返回三个月后日期时间戳
   * this.$jxUtils.date.dateAdd("M", -3) // 返回三个月前日期时间戳
   * this.$jxUtils.date.dateAdd("d", -1) // 返回一天前时间戳
   * this.$jxUtils.date.dateAdd("d", 1) // 返回一天后时间戳
   * this.$jxUtils.date.dateAdd("h", 1) // 返回一小时后时间戳
   * this.$jxUtils.date.dateAdd("h", -1) // 返回一小时前时间戳
   * this.$jxUtils.date.dateAdd("h", -1,'2021-09-01 11:20:30') // 返回 当前时间2021-09-01 11:20:30的 一小时前时间戳
   *
   */
  dateAdd(part, value, date = new Date()) {
    if (date instanceof Date) {
      date = date
    } else {
      date = new Date(date)
    }
    let tempTime
    switch (part) {
      case 'y':
        tempTime = date.setFullYear(date.getFullYear() + value)
        break
      case 'M':
        tempTime = date.setMonth(date.getMonth() + value)
        break
      case 'd':
        tempTime = date.setDate(date.getDate() + value)
        break
      case 'h':
        tempTime = date.setHours(date.getHours() + value)
        break
      case 'm':
        tempTime = date.setMinutes(date.getMinutes() + value)
        break
      case 's':
        tempTime = date.setSeconds(date.getSeconds() + value)
        break
      default:
    }
    return tempTime
  }

  /**
   * @description 出入固定格式返回 最近多天的日期 业务场景  最近3天、最近7天、最近30天、最近90天
   * @example date.latelyDate(7,'d') 组件七天 返回 [2021-09-01,2021-09-08]
   * @param {string} part 计算的日期节点  y年、M月、d日、h时、m分 、s秒
   * @param {*} value 正整数
   * @param {string} fmt 可选  时间格式 yyyy-MM-dd 2021-09-01 、 yyyy-MM-dd hh:mm:ss2014-01-01 01:20:20
   * @author xiaodong.zhang
   * @returns {Array}  [开始时间，结束时间]
   * @example
   * this.$jxUtils.date.latelyDate(7) // [2021-08-10,2021-08-17]
   * this.$jxUtils.date.latelyDate(7,'h') // [2021-08-10 10:00:00,2021-08-10 11:00:00]
   */
  latelyDate(value, part = 'd', fmt = 'yyyy-MM-dd') {
    let tempArr = []
    if (!value) {
      return [this.dateFmt(), this.dateFmt()]
    }
    if (part == 'h' || part == 'm' || part == 's') {
      fmt = 'yyyy-MM-dd hh:mm:ss'
    }
    tempArr = [this.dateFmt(fmt, this.dateAdd(part, 0 - value)), this.dateFmt(fmt)]
    return tempArr
  }
  /**
   * @description 最近 7 天
   * @param {string} fmt  default "yyyy-MM-dd hh:mm:ss"
   * @author xiaodong.zhang
   * @returns {Array} [start,end] 返回最近7天的时间段
   * @example
   * this.$jxUtils.date.lately7Date() // 最近7天 默认 年-月-日
   * this.$jxUtils.date.lately7Date("yyyy-MM-dd hh:mm:ss") // 最近7天 默认 年-月-日 时:分:秒
   */
  lately7Date(fmt = 'yyyy-MM-dd hh:mm:ss') {
    return this.latelyDate(7, 'd', fmt)
  }
  /**
   * @description 最近 30 天
   * @param {string} fmt  default "yyyy-MM-dd hh:mm:ss"
   * @author xiaodong.zhang
   * @returns {Array} [start,end] 返回最近30天的时间段
   * this.$jxUtils.date.lately30Date() // 最近7天 默认 年-月-日
   * this.$jxUtils.date.lately30Date("yyyy-MM-dd hh:mm:ss") // 最近7天 默认 年-月-日 时:分:秒
   */
  lately30Date(fmt = 'yyyy-MM-dd hh:mm:ss') {
    return this.latelyDate(30, 'd', fmt)
  }
  /**
   * @description 最近 90 天
   * @param {string} fmt  default "yyyy-MM-dd hh:mm:ss"
   * @author xiaodong.zhang
   * @returns {Array} [start,end] 返回最近90天的时间段
   * this.$jxUtils.date.lately90Date() // 最近7天 默认 年-月-日
   * this.$jxUtils.date.lately90Date("yyyy-MM-dd hh:mm:ss") // 最近7天 默认 年-月-日 时:分:秒
   */
  lately90Date(fmt = 'yyyy-MM-dd hh:mm:ss') {
    return this.latelyDate(90, 'd', fmt)
  }

  /**
   * @description 给定时间返回 n个月前 n天前 n小时前 n天前 n周前
   * @param {string} dateStr
   * @author xiaodong.zhang
   * @returns {string} {type: 'day',value: number}
   * @example
   * this.$jxUtils.date.getDateDiff('2021-09-01 11:05') // {type: 'day',value: 5}
   *
   */
  getDateDiff(dateStr) {
    let minute = 1000 * 60
    let hour = minute * 60
    let day = hour * 24
    let month = day * 30
    let now = new Date().getTime()
    let diffValue = now - this.getTimeStamp(dateStr)
    console.log(diffValue)
    if (diffValue < 0) {
      return
    }
    let monthC = diffValue / month
    let weekC = diffValue / (7 * day)
    let dayC = diffValue / day
    let hourC = diffValue / hour
    let minC = diffValue / minute
    let result = {}
    if (monthC >= 1) {
      result = {
        type: 'month',
        value: parseInt(monthC)
      }
    } else if (weekC >= 1) {
      result = {
        type: 'week',
        value: parseInt(weekC)
      }
    } else if (dayC >= 1) {
      result = {
        type: 'day',
        value: parseInt(dayC)
      }
    } else if (hourC >= 1) {
      result = {
        type: 'hour',
        value: parseInt(hourC)
      }
    } else if (minC >= 1) {
      result = {
        type: 'minute',
        value: parseInt(minC)
      }
    } else {
      result = {
        type: 'justNow',
        value: ''
      }
    }
    return result
  }

  /**
   * @description 时间转秒，03:00 = 180s 01:01:01 = 3661s
   * @param {*} time
   * @author xiaodong.zhang
   * @returns {number} 转换后的秒
   * @example
   * this.$jxUtils.date.timeToSec('03:00') // 180
   * v
   */
  timeToSec(time) {
    let reg = /^\d+:[0-5]?[0-9](:[0-5]?[0-9])?$/
    if (!reg.test(time)) {
      throw new Error('给定的时间格式有误')
    }
    let result = 0
    let len = time.split(':').length
    let hour = 0 //time.split(":")[0];
    let min = 0 // time.split(":")[1];
    let sec = 0
    if (len == 3) {
      hour = time.split(':')[0]
      min = time.split(':')[1]
      sec = time.split(':')[2]
    } else {
      hour = 0
      min = time.split(':')[0]
      sec = time.split(':')[1]
    }
    result = Number(hour * 3600) + Number(min * 60) + Number(sec)
    return result
  }

  /**
   * @description 给定时间列表，对比当前时间，比上一个大，比下一个小
   * @param {string} prev hh:mm:ss / hh:mm
   * @param {string} cur hh:mm:ss / hh:mm
   * @param {string} next hh:mm:ss / hh:mm
   * @author xiaodong.zhang
   * @returns {boolean} true / false
   * this.$jxUtils.date.diffPrevTimeNextTime('2:10','2:11','2:12') //true
   * this.$jxUtils.date.diffPrevTimeNextTime('2:10','2:09','2:12') //false
   */
  diffPrevTimeNextTime(prev, cur, next) {
    let [prevNum, curNum, nextNum] = [this.timeToSec(prev), this.timeToSec(cur), this.timeToSec(next)]
    return curNum > prevNum && curNum < nextNum ? true : false
  }

  /**
   * @description 数字专时间
   * @param {number} s
   * @param {boolean} isHour 是否小于一小时 显示 小时
   * @author xiaodong.zhang
   * @returns {string} hh:mm:ss
   * @example
   * this.$jxUtils.date.secToTime(180) // 00:03:00
   * this.$jxUtils.date.secToTime(180,true) // 03:00

   * this.$jxUtils.date.secToTime(3600) //01:00:00
   *
   */
  secToTime(s, isHour) {
    let t
    if (s > -1) {
      let hour = Math.floor(s / 3600)
      let min = Math.floor(s / 60) % 60
      let sec = s % 60
      if (hour < 10) {
        if (isHour) {
          if (hour == 0) {
            t = ''
          } else {
            t = '0' + hour + ':'
          }
        } else {
          t = '0' + hour + ':'
        }
      } else {
        t = hour + ':'
      }

      if (min < 10) {
        t += '0'
      }
      t += min + ':'
      if (sec < 10) {
        t += '0'
      }
      t += sec
    }
    return t
  }
  /**
   * 时间计算
   * @description 根据传入时间计算某个时间区时间
   * @param {Date} time 传入的时间
   * @param {number} offset 偏移量
   * @param {string} type 返回类型
   * @author xiaodong.zhang
   * @returns {number} 当地时间
   * @example
   * this.$jxUtils.date.calcTime('2021-09-11 23:00:00',9) 转换为 东9区时间
   *
   */
  calcTime(time, offset = 8, type = 'date') {
    // 转换为iso时间
    let dateee = new Date(time).toJSON()
    let date = new Date(+new Date(dateee) + offset * 3600 * 1000)
      .toISOString()
      .replace(/T/g, ' ')
      .replace(/\.[\d]{3}Z/, '')
    return type == 'date' ? date : new Date(date).getTime()
  }

  /**
   * 转换北京时间为当地时间 避免时间出现偏差
   * @param {Date} bjTime 数据库存储的北京时间
   * @param {Number} type 类型 'date'(时间字符串) | 'stamp' '时间戳'
   * @author xiaodong.zhang
   * @returns {number} localTime 时间戳
   * @example
   * this.$jxUtils.date.transBjTimeLocalTime('2015-05-09 11:29:23') // 把北京时间转换为当地时间
   */
  transBjTimeLocalTime(bjTime, type = 'date') {
    if (!bjTime) return ''
    const localDateOffset = new Date().getTimezoneOffset()
    const offset = localDateOffset / 60 < 0 ? Math.abs(localDateOffset / 60) : (-1 * localDateOffset) / 60

    return this.calcTime(bjTime, offset, type)
  }

  /**
   * 转换当地时间为北京时间 统一北京时间入库
   * @param {Date} dateForm 用户选择时间
   * @param {Number} type 类型 'date'(时间字符串) | 'stamp' '时间戳'
   * @author xiaodong.zhang
   * @returns {string} BJTime 时间戳
   * @example
   * this.$jxUtils.date.transLocalTimeBjTime('2015-05-09 11:29:23') // 返回转换后的北京时间
   */
  transLocalTimeBjTime(dateForm, type = 'date') {
    if (!dateForm) {
      return ''
    } else {
      let offset = 8
      return this.calcTime(dateForm, offset, type)
    }
  }
}

const vhDate = new JxDateClass()

export default vhDate
